package com.fortune.rainshine.system.controller;

import com.fortune.rainshine.common.BaseController;
import com.fortune.rainshine.common.JsonResult;
import com.fortune.rainshine.common.utils.StringUtil;
import com.fortune.rainshine.common.utils.UserAgentGetter;
import com.fortune.rainshine.service.service.ShopService;
import com.fortune.rainshine.system.service.AuthoritiesService;
import com.fortune.rainshine.system.service.LoginRecordService;
import com.fortune.rainshine.system.service.MessageService;
import com.fortune.rainshine.system.service.RoleService;
import com.fortune.rainshine.system.service.UserService;
import com.fortune.rainshinecommon.model.ShopModel;
import com.fortune.rainshinecommon.model.system.Authorities;
import com.fortune.rainshinecommon.model.system.LoginRecord;
import com.fortune.rainshinecommon.model.system.Role;
import com.fortune.rainshinecommon.model.system.User;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * MainController
 */
@Controller
public class MainController extends BaseController implements ErrorController {
	private static final Logger logger = LoggerFactory.getLogger(MainController.class);

	@Autowired
	private AuthoritiesService authoritiesService;
	@Autowired
	private LoginRecordService loginRecordService;
	@Autowired
	private DefaultKaptcha defaultKaptcha;
	@Autowired
    private ShopService shopService;
	@Autowired
    private RoleService roleService;
	@Autowired
	private UserService userService;
	@Autowired
    private MessageService messageService;

	/**
	 * 主页
	 */
	@RequestMapping({ "/", "/index" })
	public String index(Model model) {
		List<Authorities> authorities = authoritiesService.listByUserId(getLoginUserId());
		List<Map<String, Object>> menuTree = getMenuTree(authorities, -1);
		User user = getLoginUser();
		boolean shopShow = false;
		List<Role> role = roleService.getByUserId(user.getUserId());
		int roleId = role.get(0).getRoleId();
		List<ShopModel> shop = new ArrayList<>();
		//判断为店员
		if(roleId == 3) {
			ShopModel shop1 = shopService.getShopByShopId2(user.getShopId());
			if(shop1.getId() != null) {
				shopShow = true;
				shop.add(shop1);
			}
			
		}else {
			shop = shopService.getShopsByUserId2(user.getUserId());
			if(shop.size() > 0 && roleId != 1) {
				shopShow = true;
			}else if(roleId == 1) {
				shopShow = true;
			}
		}
		
		Map<String,Integer> map = messageService.selectCount(user.getUserId());

		model.addAttribute("total", map.get("num12")+map.get("num3"));
		model.addAttribute("shops", shop);
		model.addAttribute("menus", menuTree);
		model.addAttribute("login_user", user);
		model.addAttribute("roleId", roleId);
		if(shopShow) {
			return "index.html";
		}else {
			return "error/lose.html";
		}
		
	}
	
	/**
	 * 商铺切换重新加载
	 */
	@RequestMapping("/{shopId}" )
	public String shopChange(@PathVariable Integer shopId,Model model) {
		List<Authorities> authorities = authoritiesService.listByUserId(getLoginUserId());
		List<Map<String, Object>> menuTree = getMenuTree(authorities, -1);
		User user = getLoginUser();
		List<ShopModel> shop = shopService.getShopsByUserId(user.getUserId());
		if(shop.size() > 1) {
			for (int i = 0;i<shop.size();i++){
				if(shop.get(i).getId() == shopId) {
					Collections.swap(shop, i, 0);
				}
		    }
		}
		int roleId =this.getLoginUserRole().getRoleId();
		Map<String,Integer> map = messageService.selectCount(user.getUserId());

		model.addAttribute("total", map.get("num12")+map.get("num3"));
		model.addAttribute("shops", shop);
		model.addAttribute("menus", menuTree);
		model.addAttribute("login_user", user);
		model.addAttribute("roleId", roleId);
		return "index.html";
	}

	/**
	 * 登录页
	 */
	@GetMapping("/login")
	public String login() {
		if (getLoginUser() != null) {
			return "redirect:index";
		}
		return "login.html";
	}

	/**
	 * 登录
	 */
	@ResponseBody
	@PostMapping("/login")
	public JsonResult doLogin(String username, String password, String code, HttpServletRequest request) {
		// 获取图形验证码，若为空则说明而已调用短信接口
		if(request.getSession().getAttribute("vercode") == null ){
			return JsonResult.error("无法获取验证码");
		}
		String vcode = request.getSession().getAttribute("vercode").toString().toUpperCase();

		if (StringUtil.isBlank(username, password)) {
			return JsonResult.error("帐号密码不能为空");
		}
		if (!vcode.equals(code.toUpperCase())) {
			return JsonResult.error("验证码不正确");
		}
		try {
			UsernamePasswordToken token = new UsernamePasswordToken(username, password);
			SecurityUtils.getSubject().login(token);
			addLoginRecord(getLoginUserId(), request);
			return JsonResult.ok("登录成功");
		} catch (IncorrectCredentialsException ice) {
			return JsonResult.error("密码错误");
		} catch (UnknownAccountException uae) {
			return JsonResult.error("帐号不存在");
		} catch (LockedAccountException e) {
			return JsonResult.error("帐号被锁定");
		} catch (ExcessiveAttemptsException eae) {
			return JsonResult.error("操作频繁，请稍后再试");
		}
	}

	/**
	 * 图形验证码，用assets开头可以排除shiro拦截
	 */
	@RequestMapping("/assets/captcha")
	public void captcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
			throws IOException {
		byte[] captchaChallengeAsJpeg;
		ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
		try {
			String createText = defaultKaptcha.createText();
			httpServletRequest.getSession().setAttribute("vercode", createText);

			BufferedImage challenge = defaultKaptcha.createImage(createText);
			ImageIO.write(challenge, "jpg", jpegOutputStream);

			captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
			httpServletResponse.setHeader("Cache-Control", "no-store");
			httpServletResponse.setHeader("Pragma", "no-cache");
			httpServletResponse.setDateHeader("Expires", 0);
			httpServletResponse.setContentType("image/jpeg");
			ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
			responseOutputStream.write(captchaChallengeAsJpeg);
			responseOutputStream.flush();
			responseOutputStream.close();
		} catch (Exception e) {
			logger.info("获取图形验证码失败", e);
			e.printStackTrace();
			httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
		}
	}

	/**
	 * iframe页
	 */
	@RequestMapping("/iframe")
	public String error(String url, Model model) {
		model.addAttribute("url", url);
		return "tpl/iframe.html";
	}

	/**
	 * 错误页
	 */
	@RequestMapping("/error")
	public String error(String code) {
		if ("403".equals(code)) {
			return "error/403.html";
		}
		return "error/404.html";
	}

	@Override
	public String getErrorPath() {
		return "/error";
	}

	/**
	 * 递归转化树形菜单
	 */
	private List<Map<String, Object>> getMenuTree(List<Authorities> authorities, Integer parentId) {
		List<Map<String, Object>> list = new ArrayList<>();
		for (int i = 0; i < authorities.size(); i++) {
			Authorities temp = authorities.get(i);
			if (temp.getIsMenu() == 0 && parentId == temp.getParentId()) {
				Map<String, Object> map = new HashMap<>();
				map.put("menuName", temp.getAuthorityName());
				map.put("menuIcon", temp.getMenuIcon());
				map.put("menuUrl", StringUtil.isBlank(temp.getMenuUrl()) ? "javascript:;" : temp.getMenuUrl());
				map.put("subMenus", getMenuTree(authorities, authorities.get(i).getAuthorityId()));
				list.add(map);
			}
		}
		return list;
	}

	/**
	 * 添加登录日志
	 */
	private void addLoginRecord(Integer userId, HttpServletRequest request) {
		UserAgentGetter agentGetter = new UserAgentGetter(request);
		// 添加到登录日志
		LoginRecord loginRecord = new LoginRecord();
		loginRecord.setUserId(userId);
		loginRecord.setOsName(agentGetter.getOS());
		loginRecord.setDevice(agentGetter.getDevice());
		loginRecord.setBrowserType(agentGetter.getBrowser());
		loginRecord.setIpAddress(agentGetter.getIpAddr());
		loginRecordService.add(loginRecord);
	}

}
